home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / lang / c++-part1 / 743 < prev    next >
Encoding:
Internet Message Format  |  1996-08-06  |  3.2 KB

  1. Path: INbe.net!user
  2. From: cbasti@innet.be (Chris Bastiaens)
  3. Newsgroups: comp.lang.c++,comp.sys.mac.programmer.codewarrior,comp.sys.mac.oop
  4. Subject: Re: Help needed with Runtime Type Info
  5. Date: Sat, 06 Jan 1996 20:48:24 +0100
  6. Organization: Agfa Gevaert, N.V.
  7. Distribution: world
  8. Message-ID: <AD1490989668197DC@pool03-12.innet.be>
  9. References: <pcal-0401962039480001@slip-d8.rdrop.com>
  10. NNTP-Posting-Host: pool03-12.innet.be
  11.  
  12. In article <pcal-0401962039480001@slip-d8.rdrop.com>,
  13. pcal@agora.rdrop.com (Patrick Calahan) wrote:
  14.  
  15. >     I have an abstract class B from which D,E and F are derived
  16. >     
  17. >     I also have an abstract class O from which P, Q and R are derived.
  18. >     
  19. >     Objects derived from O need to perform specific operations given a 
  20. >     pair of pointers to B's. The operation to be performed depends on 
  21. >     precisely  what kind of B's are given to the O.
  22. >     
  23. >     I thought that by simply overloading member function f in the O's,
  24. >     I could achieve this affect nicely - f(D*,D*), f(D*,E*), f(E*,F*)...
  25. >     could be defined to handle the particualr pair-cases appropriately.
  26. >     A member function in O f(B*,B*) would handle all cases not handled
  27. >     specifically by the subclasses.
  28. >     
  29. >     The only problem is figuring out exactly what type of object a B* is
  30. >     pointing to so that the appropriate call to O.f can be made.  I.e.,
  31. >     given a pointer to a B, I need to cast it to a D*,E*, or F*.
  32. >     
  33. >     On page 640 of Stroustrup, he says that [in dynamic_cast<t>(v)]
  34. >     "If T is void* then v must be a pointer, and the result value is a
  35. >     pointer to the complete object pointed to by v."
  36. >
  37. >     So, if I read him correctly,
  38. >     
  39. >     dynamic_cast<void*>(p*)
  40. >     
  41. >     should cast p to a pointer to an object of the most complete type of 
  42. >     the object pointed to by p, i.e. cast my B* to an D*, E* or F*.
  43. >     This sounds like what I want.
  44. >     
  45. >     Unfortunately, if I try to compile the following using MetroWerks
  46. >     CodeWarrior 7 (I do have RTTI enabled):
  47. >     
  48. >     
  49. >     some_function(B* b1, B*b2, O* o)
  50. >     {
  51. >
  52. >     // here I need to figure out what types of objects b1 & b2 really are
  53. >     // and cast the pointers so the correct version of f will be called.
  54. >     
  55. >     o->f( dynamic_cast<void*>(b1), dynamic_cast<void*>(b2) );
  56. >     
  57. >     }
  58. >     
  59. >     
  60. >     b1 and b2 apparently get cast to void*; the compiler returns that
  61. >      f(void*,void*) can't be found.
  62.  
  63. Patrick,
  64.  
  65. I don't have Stroustroup's book at hand, but from what I know about RTTI, I
  66. think code like the following should do what you want:
  67.  
  68. O::HandleBs(B *b1, B *b2)
  69. {
  70.     D *d1 = dynamic_cast<D *>(b1), *d2 = dynamic_cast<D *>(b2);
  71.     E *e1 = dynamic_cast<E *>(b1), *e2 = dynamic_cast<E *>(b2);
  72.     F *f1 = dynamic_cast<F *>(b1), *f2 = dynamic_cast<F *>(b2);
  73.  
  74.     if (d1 && d2) f(d1, d2) else
  75.  if (d1 && e2) f(d1, e2) else
  76.  if (d1 && f2) f(d1, f2) else
  77.     if (e1 && d2) f(e1, d2) else
  78.  if (e1 && e2) f(e1, e2) else
  79.  if (e1 && f2) f(e1, f2) else
  80.     if (f1 && d2) f(f1, d2) else
  81.  if (f1 && e2) f(f1, e2) else
  82.  if (f1 && f2) f(f1, f2)
  83. }
  84.  
  85. Not that this supposes class hierarchy like this:
  86.  
  87.    B
  88.   /|\
  89.  / | \
  90. /  |  \
  91. D  E  F
  92.  
  93. and not, for instance, like
  94.    B
  95.   /|
  96.  / |
  97. /  |
  98. D  E
  99.    |
  100.    F
  101. because in that case, an F* is also an E*.
  102.  
  103.  
  104.  
  105.